package com.hqyj.aop;


import com.hqyj.pojo.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;

//表示一个切面类
@Aspect
@Component
public class TestAop {

    //定义你要拦截的方法(切入的方法)的位置(层面)
    //切入点表达式语法： 作用域  包名.类(*匹配所有类).方法(*匹配所有方法).参数(..通配方法的所有参数)
    @Pointcut("execution(* com.hqyj.controller.*.*(..))")
    public void pointcut() {

    }

    //1 切入servevice的某个类的具体方法
    @Pointcut("execution(* com.hqyj.service.impl.UserServiceImpl.regist(..))")
    public void servicePoint() {

    }

    //前置通知
    @Before("servicePoint()")
    public void selectListBefore() {
        System.out.println("运行前置通知");
    }

    //后置通知
    @After("servicePoint()")
    public void selectListAfter() {
        System.out.println("运行后置通知");
    }

    //后置返回值通知
    @AfterReturning(returning = "ret", pointcut = "servicePoint()")
    public void selectListAfterV(Object ret) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map = (HashMap<String, Object>) ret;
        System.out.println("ret=" + ret);
        System.out.println("map=" + map);
    }

    //环绕通知
    @Around("servicePoint()")
    public Object selectListAround(ProceedingJoinPoint pjp) {
        Object obj = null;
        try {
            System.out.println("方法之前执行");
            System.out.println("方法参数：" + Arrays.toString(pjp.getArgs()));
            Object[] o = pjp.getArgs();
            User a = (User) o[0];
            if (a.getUserName().equals("大司马")) {
                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put("info", "不要假装我的金轮🤒");
                return map;
            }
            //获取方法的返回值
            obj = pjp.proceed();
            System.out.println("方法之后执行");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return obj;
    }

    //
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        //从aop中获取request对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String userName = request.getSession().getAttribute("user") + "";
        if (userName.equals("admin")) {
            //重定向：两次转发，且request是新的
            return "redirect:/login.jsp";
        }
        //放行
        Object obj = pjp.proceed();
        return obj;
    }

}
